﻿using AbpApplication.Expand;
using AbpEntityFrameworkcore.DbContext;
using AbpToDomain.EntityInfo;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using NStandard;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using AbpApplication.InPut;
using Application.Expand;
using Volo.Abp.Users;
using AbpApplication.Flurl;
using AbpEntityFrameworkcore;
using OfficeOpenXml;
using Microsoft.AspNetCore.Http;
using System.Data;
using LinqSharp;
using AbpApplication.AppServices.BaseRequest;
using AbpToDomain.View;
using System.Linq.Dynamic.Core;
using System.Net;
using System.Net.Sockets;
using Microsoft.AspNetCore.SignalR.Client;
using SingalR.Client;
using Flurl.Http;
using Microsoft.Identity.Client;
using Newtonsoft.Json;
using OfficeOpenXml.FormulaParsing.Ranges;
using AbpApplication.Dto;
using Azure;
using MediatR;
using Azure.Core;

namespace AbpApplication.AppServices
{
    ///<inheritdoc/>
    public class BaseService : ApplicationService, IBaseService, INotificationHandler<PostNotification>
    {


        private readonly IRepository<lognote> LogNote_res;
        private readonly ICurrentUser User;
        private readonly IRepository<Position> position_res;
        private readonly IRepository<TaskOrder> taskOrder_res;
        private readonly IRepository<MaterialList> materiallist_res;
        private readonly IRepository<TaskInfo> taskinfo_res; 
        private readonly IMediator Mediator;
       




        public static bool IsDebug;

        private readonly MyDbContext context;
        private readonly ILoginHelper loginHelper;
        public BaseService(IRepository<Position> position_res, IRepository<TaskOrder> taskOrder_res, IRepository<lognote> logNote_res, MyDbContext context,
            IRepository<MaterialList> materiallist_res, IMediator mediator
, IRepository<TaskInfo> taskinfo_res)
        {
            this.position_res = position_res;
            this.taskOrder_res = taskOrder_res;
            LogNote_res = logNote_res;
            this.context = context;
            this.materiallist_res = materiallist_res;
            Mediator = mediator;
            this.taskinfo_res = taskinfo_res;
        }
        //任务回调
        public async Task<ApiResponse> CallAGVBack(CallByRequest Request)
        {
            //create log
     
            TaskOrder  taskOrder=  await taskOrder_res.FirstOrDefaultAsync(x => x.TaskOrderCode == Request.pdataskId);
            if (taskOrder == null)
            {
                lognote log = new lognote() { Type = "任务回调-未查询到任务", User = "AGV", Note = Request.Type +Request.pdataskId, DateTime = DateTime.Now };
                await LogNote_res.InsertAsync(log);
                return new ApiResponse("未查询到任务", false, null);
            }
            if (Request.Type == "Totofinish")
            {
              Position  position=   await position_res.FirstOrDefaultAsync(x => x.Position_Id == taskOrder.Origination_Id);
                if (position !=null)
                {
                    lognote log = new lognote() { Type = "任务回调-动作完成", User = "AGV", Note = $"起始点{position.PositionCode}"+   Request.Type + Request.pdataskId, DateTime = DateTime.Now };
                    await LogNote_res.InsertAsync(log);
                    position.IsOccupy=false;
                    position.IsExist = false;
                    await position_res.UpdateAsync(position);
                };
            }
            if (Request.Type == "taskfinish")
            {

                Position position = await position_res.FirstOrDefaultAsync(x => x.Position_Id == taskOrder.Target_Id);
                if (position != null)
                {
                    position.IsExist=true;
                    lognote log = new lognote() { Type = "任务回调-任务完成", User = "AGV", Note =$"目标点{position.PositionCode}"+  Request.Type + Request.pdataskId, DateTime = DateTime.Now };
                    await LogNote_res.InsertAsync(log);
                    await taskOrder_res.DeleteAsync(taskOrder);
                    await position_res.UpdateAsync(position);
                }
            }
            else
            {
                lognote log = new lognote() { Type = "任务回调-参数有误", User = "AGV", Note = Request.Type + Request.pdataskId, DateTime = DateTime.Now };
                return new ApiResponse("参数有误", false, null);
            }

                return new ApiResponse("接收成功", true, null);
        }


        //库位生成
        public async Task<ApiResponse> CreatePosition(Request_Base1 Request)
        {
            List<Position> positions = new List<Position>();
            for (int i = 1; i <= Request.PostitionQuantity; i++)
            {
                Position position=new Position();
                position.PositionCode = Request.PositionCode +-+i;
                position.PostionZone = Request.PositionCode;
                position.Type = Request.Type;
                position.IsOccupy = false;
                position.IsEnabled = true;
                positions.Add(position);


            }
            await position_res.InsertManyAsync(positions);
            return new ApiResponse("创建成功", true, positions);
        }
        //创建产线去仓库任务单
        public async Task<ApiResponse> CreateTaskOrder(Request_Base2 Request)
        {


            TaskInfo taskInfo=new TaskInfo();
            taskInfo.StartName = Request.Origination_Code;
            taskInfo.EndName = Request.Target_Code;
            taskInfo.CreateTime = DateTime.Now;
            taskInfo.IsFinsih = false;
            taskInfo.Type = "产线仓库";
          
            await taskinfo_res.InsertAsync(taskInfo);
            //create log
            lognote log = new lognote() { Type = "添加任务", User = "App", Note = $"-起始库位{Request.Origination_Code}-目标{Request.Target_Code}", DateTime = DateTime.Now };
            return new ApiResponse("创建成功", true, taskInfo);

            //bool Check=  await taskOrder_res.AnyAsync(x => x.Target.PositionCode == Request.Target_Code);

            //Position Orginationposition = await position_res.FirstOrDefaultAsync(x=>x.PositionCode == Request.Origination_Code);
            //if (Orginationposition == null)
            //{
            //    return new ApiResponse("原库位不存在", false, null);
            //}
            //Position Targetposition=await position_res.FirstOrDefaultAsync(x=>x.PositionCode == Request.Target_Code);
            //if (Targetposition == null)
            //{
            //    return new ApiResponse("目标库位不存在", false, null);
            //}
            //if(!IsDebug)
            //{
            //    //if (Targetposition.Type == "缓存区")
            //    //{
            //    //    if (Targetposition.IsOccupy)
            //    //    {
            //    //        return new ApiResponse("目标库位已被占用", false, null);
            //    //    }
            //    //    if (Check)
            //    //    {
            //    //        return new ApiResponse("该目标库位已存在任务单", false, null);
            //    //    }
            //    //}
            //}
            ////create taskorder
            //TaskOrder taskOrder = new TaskOrder();
            //taskOrder.TaskOrderCode = ExtendRandom.CreateRandom();
            //taskOrder.CreateTime = DateTime.Now;
            //taskOrder.Target = Targetposition;
            //taskOrder.Origination = Orginationposition;
            //taskOrder.Target.IsOccupy = true;
            ////create log
            //lognote log = new lognote() { Type = "添加任务", User = "App", Note = $"单号-{taskOrder.TaskOrderCode}-目标库位{taskOrder.Target.PositionCode}-起始目标{taskOrder.Origination.PositionCode}", DateTime = DateTime.Now };
            ////savechange
            //await taskOrder_res.InsertAsync(taskOrder);
            //await LogNote_res.InsertAsync(log);

        }
        //创建去虚拟位任务
        public async Task<ApiResponse> CreateFromCachaTaskOrder()
        {
            TaskInfo taskInfo = new TaskInfo();
            taskInfo.StartName = "缓存";
            taskInfo.EndName = "Loc-9-1";
            taskInfo.CreateTime = DateTime.Now;
            taskInfo.IsFinsih = false;
            taskInfo.Type = "缓存虚拟位";
            taskInfo.Counter = 0;
            await taskinfo_res.InsertAsync(taskInfo);
            //create log
            lognote log = new lognote() { Type = "添加任务", User = "App", Note = $"-起始库位{"缓存"}-目标{"虚拟位"}", DateTime = DateTime.Now };
            return new ApiResponse("创建成功", true, taskInfo);
            //Position Orginationposition = await position_res.FirstOrDefaultAsync(x => x.IsExist ==true&&x.Type=="缓存区");
            //if (Orginationposition == null)
            //{
            //   Orginationposition = await position_res.FirstOrDefaultAsync(x=>x.Type == "缓存区");
            //}
            //Position Targetposition = await position_res.FirstOrDefaultAsync(x => x.PositionCode.Contains("Loc-7-1"));
            //TaskOrder taskOrder = new TaskOrder();
            //taskOrder.TaskOrderCode = ExtendRandom.CreateRandom();
            //taskOrder.CreateTime = DateTime.Now;
            //taskOrder.Target = Targetposition;
            //taskOrder.Origination = Orginationposition;
            //taskOrder.Target.IsOccupy = true;
            ////create log
            //lognote log = new lognote() { Type = "添加任务", User = "App", Note = $"单号-{taskOrder.TaskOrderCode}-目标库位{taskOrder.Target.PositionCode}-起始目标{taskOrder.Origination.PositionCode}", DateTime = DateTime.Now };
            ////savechange
            //await taskOrder_res.InsertAsync(taskOrder);
            //await LogNote_res.InsertAsync(log);
            //return new ApiResponse("创建成功", true, taskOrder);

        }
        //创建去缓存任务
        public async Task<ApiResponse> CreateToCacheTaskOrder(Request_Base8 Request)
        {
            TaskInfo taskInfo = new TaskInfo();
            taskInfo.StartName = Request.Origination_Code;
            taskInfo.EndName = "缓存";
            taskInfo.CreateTime = DateTime.Now;
            taskInfo.IsFinsih = false;
            taskInfo.Type = "仓库缓存";
            taskInfo.Counter = 0;
            await taskinfo_res.InsertAsync(taskInfo);
            //create log
            lognote log = new lognote() { Type = "添加任务", User = "App", Note = $"-起始库位{"仓库"}-目标{"缓存"}", DateTime = DateTime.Now };
            return new ApiResponse("创建成功", true, taskInfo);
            //Position Orginationposition = await position_res.FirstOrDefaultAsync(x => x.PositionCode == Request.Origination_Code);
            //if (Orginationposition == null)
            //{
            //    return new ApiResponse("原库位不存在", false, null);
            //}
            //Position Targetposition = await position_res.FirstOrDefaultAsync(x=>x.IsOccupy == false&&x.Type=="缓存区");
            //if (Targetposition == null)
            //{
            // Targetposition = await position_res.FirstOrDefaultAsync(x =>x.Type == "缓存区");
            //}
            //TaskOrder taskOrder = new TaskOrder();
            //taskOrder.TaskOrderCode = ExtendRandom.CreateRandom();
            //taskOrder.CreateTime = DateTime.Now;
            //taskOrder.Target = Targetposition;
            //taskOrder.Origination = Orginationposition;
            //taskOrder.Target.IsOccupy = true;


            ////create log
            //lognote log = new lognote() { Type = "添加任务", User = "App", Note = $"单号-{taskOrder.TaskOrderCode}-目标库位{taskOrder.Target.PositionCode}-起始目标{taskOrder.Origination.PositionCode}", DateTime = DateTime.Now };
            ////savechange
            //await taskOrder_res.InsertAsync(taskOrder);
            //await LogNote_res.InsertAsync(log);
            //return new ApiResponse("创建成功", true, taskOrder);
        }
        //区域视图
        public async Task<ApiResponse> GetView_PositionState(Request_Base3 Request)
        {
          var data= context.Positions.Where(x=>x.Type==Request.Type).ToList();
            return new ApiResponse("Huo",true,data );
        }
        //获取任务单视图
        public async Task<ApiResponse> GetView_TaskOrder()
        {
            var  view_Taskorders=  await context.View_TaskOrders.ToListAsync();
            return new ApiResponse("获取成功", true, view_Taskorders);
        }  
        //测试
        public async Task<ApiResponse> test(bool Enabled)
        {

            if (IsDebug)
            {
                IsDebug = false;
            }
            else
            {
                IsDebug = true;
            }
            //Tuple<string, HubConnection> tuple = await SingalrMethod.GetConnectionAsync("测试", null, null);
            List<string> localIPv4 = new List<string>();
            var host = Dns.GetHostEntry(Dns.GetHostName());
            foreach (var ip in host.AddressList)
            {
                if (ip.AddressFamily == AddressFamily.InterNetwork)
                {
                    localIPv4.Add(ip.ToString());

                }

            }


            //Mediator.Publish(new PostNotification("我发布一条消息" + DateTime.Now));
            return new ApiResponse("获取成功", true, "localIPv4"+"是否测试"+IsDebug);
        }
        //取消任务
        public async Task<ApiResponse> CancelTaskOrder(Request_Base4 Request)
        {
            TaskOrder taskOrder=   await taskOrder_res.FirstOrDefaultAsync(x=>x.TaskOrderCode==Request.TaskOrderCode);
            if (taskOrder == null)
            {
                return new ApiResponse("未查询到任务单", false, null);
            }
            Position position=   await  position_res. FirstOrDefaultAsync(x=>x.Position_Id == taskOrder.Target_Id);
            if(position == null)
            {
                return new ApiResponse("未查询到库位", false, null);
            }
            position.IsOccupy = false;
            //AgvRequest2 agvRequest = new AgvRequest2();
            //agvRequest.pdataskId = taskOrder.TaskOrderCode;
            //agvRequest.releaseSite = "1";
            //var url = $"http://10.10.3.76:8080/script-api/stop-task";
            //var data = agvRequest;
            //string result = await url.PostJsonAsync(data).ReceiveString();
            //ApiResponse_AGV Response = JsonConvert.DeserializeObject<ApiResponse_AGV>(result);
            //if (Response.mes != "Success")
            //{
            //    return new ApiResponse("agv取消失败", false, null);
            //}
            await position_res.UpdateAsync(position);
            await taskOrder_res.DeleteAsync(taskOrder);
            //create log
            lognote logfail = new lognote() { Type = "任务取消", User = "App", Note = $"单号-{taskOrder.TaskOrderCode}-目标库位{taskOrder.Target_Id}-起始目标{taskOrder.Origination_Id}", DateTime = DateTime.Now };
            await LogNote_res.InsertAsync(logfail);
            return new ApiResponse("取消成功", true, null);
        }
        //添加物料
        public async Task<ApiResponse> CreateMaterialList(Request_Base5 Request)
        {
          MaterialList materialListCheck=  await materiallist_res.FirstOrDefaultAsync(x => x.MaterialList_Name == Request.MaterialList_Name);
            if (materialListCheck != null)
            {
                return new ApiResponse("该物料已存在", false, null);
            }

            MaterialList materialList = new MaterialList();
            materialList.MaterialList_Name = Request.MaterialList_Name;
            materialList.Description = Request.Description;
            materialList.Target = Request.Target;
            await context.MaterialLists.AddAsync(materialList);
            await context.SaveChangesAsync();
            return new ApiResponse("添加成功", true, null);
        }
        //获取物料列表
        public async Task<ApiResponse> GetMaterialList(Request_Base6 Request)
        {
           var materiallist=     await context.MaterialLists.ToListAsync();
            if ( !string.IsNullOrEmpty( Request.MaterialList_Name))
            {
                materiallist=materiallist.Where(x=>x.MaterialList_Name.Contains(Request.MaterialList_Name)).ToList();
            }
            if (!string.IsNullOrEmpty(Request.Target))
            {
                materiallist = materiallist.Where(x => x.Target.Contains(Request.Target)).ToList();
            }
            materiallist = materiallist.Take(100).ToList();
            return new ApiResponse("获取成功", true, materiallist);
        }
        //搜索物料
        public async Task<ApiResponse> SearchMaterialList(Request_Base7 Request)
        {

            Request.MaterialList_Name = Request.MaterialList_Name.Replace(" ", "");
         MaterialList materialList=    await context.MaterialLists.Where(x=>Request.MaterialList_Name.Contains(x.MaterialList_Name)).FirstOrDefaultAsync();
            if (materialList == null)
            {
                return new ApiResponse("未查询到物料", false, "未查询到物料");
            }
            return new ApiResponse("获取成功", true, materialList.Target);
        }
        //队列视图
        public async Task<ApiResponse> GetView_TaskOrderInfo()
        {
          var data =  await context.TaskInfos.Where(x => x.IsFinsih == false).ToListAsync();
            return new ApiResponse("获取成功", true, data);
        }
        //轮询任务
        public async Task<ApiResponse> PollingTask()
        {
            bool lockGo= false;

            List<TaskInfo> taskInfos = await context.TaskInfos.Where(x => x.IsFinsih == false).OrderBy(x => x.Counter).ToListAsync();
            foreach (var taskInfo in taskInfos)
            {
                if (lockGo)
                {
                    lognote logfail = new lognote() { Type = "lock", User = "App", Note = $" 锁未打开", DateTime = DateTime.Now };
                    await LogNote_res.InsertAsync(logfail);
                    return new ApiResponse("", false, null);
                }

                TaskOrder taskOrder = new TaskOrder();
                if (taskInfo.Type == "产线仓库")
                {
                    Position Orginationposition = await context.Positions.FirstOrDefaultAsync(x => x.PositionCode == taskInfo.StartName);
                    Position Targetposition = await context.Positions.FirstOrDefaultAsync(x => x.PositionCode == taskInfo.EndName);
                    taskOrder.TaskOrderCode = ExtendRandom.CreateRandom();
                    taskOrder.CreateTime = DateTime.Now;
                    taskOrder.Target = Targetposition;
                    taskOrder.Origination = Orginationposition;
                    taskOrder.Target.IsOccupy = true;
                    taskOrder.Info = taskInfo.TaskInfo_id.ToString();
                    taskOrder.IsSend = false;

                }
                if (taskInfo.Type == "仓库缓存")
                {

                    Position Orginationposition = await context.Positions.FirstOrDefaultAsync(x => x.PositionCode == taskInfo.StartName);
                    Position Targetposition = await context.Positions.FirstOrDefaultAsync(x => x.IsOccupy == false && x.Type == "缓存区");
                    if (Targetposition == null || Orginationposition == null)
                    {
                        lognote logfail = new lognote() { Type = "缓存区-未查询到空闲库位", User = "App", Note = $" type-{taskInfo.Type}+id{taskInfo.TaskInfo_id}", DateTime = DateTime.Now };
                        context.lognotes.Add(logfail);
                        taskInfo.Counter++;
                        continue;
                        //await context.SaveChangesAsync();
                        //return new ApiResponse("缓存区-未查询到空闲库位", false, null);
                    }
                    taskOrder.TaskOrderCode = ExtendRandom.CreateRandom();
                    taskOrder.CreateTime = DateTime.Now;
                    taskOrder.Target = Targetposition;
                    taskOrder.Origination = Orginationposition;
                    taskOrder.Target.IsOccupy = true;
                    taskOrder.Info = taskInfo.TaskInfo_id.ToString();
                    taskOrder.IsSend = false;
                }
                if (taskInfo.Type == "缓存虚拟位")
                {
                    if (context.TaskOrders.Any(x => x.Target.Type == "虚拟位"))
                    {
                        lognote logfail = new lognote() { Type = "缓存区-虚拟位任务存在", User = "App", Note = $" type-{taskInfo.Type}+id{taskInfo.TaskInfo_id}", DateTime = DateTime.Now };
                        context.lognotes.Add(logfail);
                        taskInfo.Counter++;
                        continue;
 
                    }
                    Position Orginationposition = await context.Positions.FirstOrDefaultAsync(x => x.IsExist == true && x.Type == "缓存区");
                    Position Targetposition = await context.Positions.FirstOrDefaultAsync(x => x.PositionCode.Contains("Loc-9-1"));
                    if (Targetposition == null || Orginationposition == null)
                    {
                        lognote logfail = new lognote() { Type = "缓存区-未查询到货架", User = "App", Note = $" type-{taskInfo.Type}+id{taskInfo.TaskInfo_id}", DateTime = DateTime.Now };
                        context.lognotes.Add(logfail);
                        taskInfo.Counter++;
                        continue;

                    }
                    taskOrder.TaskOrderCode = ExtendRandom.CreateRandom();
                    taskOrder.CreateTime = DateTime.Now;
                    taskOrder.Target = Targetposition;
                    taskOrder.Origination = Orginationposition;
                    taskOrder.Target.IsOccupy = true;
                    taskOrder.Info = taskInfo.TaskInfo_id.ToString();
                    taskOrder.IsSend = false;
                }
                try
                {
                    lockGo = true;
                    AgvRequest agvRequest = new AgvRequest();
                    agvRequest.pdataskId = taskOrder.TaskOrderCode;
                    agvRequest.startPoint = taskOrder.Origination.PositionCode;
                    agvRequest.endPoint = taskOrder.Target.PositionCode;
                    var url = $"http://10.10.3.76:8080/script-api/httpDemo";
                    var data = agvRequest;
                    string result =await  url.PostJsonAsync(data).ReceiveString();
                    ApiResponse_AGV Response = JsonConvert.DeserializeObject<ApiResponse_AGV>(result);
                    if (Response.mes != "success")
                    {
                        lognote logfail = new lognote() { Type = "任务失败", User = "App", Note = $" - 单号-{taskOrder.TaskOrderCode}-目标库位{taskOrder.Target.PositionCode}-起始目标{taskOrder.Origination.PositionCode}-返回{Response.mes}-{Response.code}-taskinfo{taskInfo.TaskInfo_id}", DateTime = DateTime.Now };
                        context.lognotes.Add(logfail);
                        await context.SaveChangesAsync();
                        return new ApiResponse("轮询失败", true, null);
                    }
                    else
                    {
                        taskInfo.IsFinsih = true;
                        taskInfo.UpdateTime = DateTime.Now;
                        taskOrder.IsSend = true;
                        context.TaskOrders.Add(taskOrder);
                        lognote logfail = new lognote() { Type = "发送任务", User = "App", Note = $"  单号-{taskOrder.TaskOrderCode}-目标库位{taskOrder.Target.PositionCode}-起始目标{taskOrder.Origination.PositionCode}-taskinfo{taskInfo.TaskInfo_id}", DateTime = DateTime.Now };
                        context.lognotes.Add(logfail);
                        await context.SaveChangesAsync();
                        lockGo = false;
                        return new ApiResponse("轮询成功", true, null);

                    }

                }
                catch (Exception ex)
                {
                    lognote logfail = new lognote() { Type = "任务失败", User = "App", Note = $" - 单号-{taskOrder.TaskOrderCode}-目标库位{taskOrder.Target.PositionCode}-起始目标{taskOrder.Origination.PositionCode}-返回{ex.Message}-taskinfo{taskInfo.TaskInfo_id}", DateTime = DateTime.Now };
                    context.lognotes.Add(logfail);
                    await context.SaveChangesAsync();
                    return new ApiResponse("轮询失败", true, null);
                }

            }

            return new ApiResponse("轮询成功", true, null);





        }
        //取消队列
        public async Task<ApiResponse> DeleteTaskInfo(Guid taskinfo_Id)
        {
           TaskInfo taskInfo=  await taskinfo_res.FirstOrDefaultAsync(x=>x.TaskInfo_id==taskinfo_Id);
            if(taskInfo==null)
            {
                return new ApiResponse("未查询到任务", false, null);
            }
            if(taskInfo.IsFinsih)
            {
                return new ApiResponse("任务已发送,无法取消", false, null);
            }
            await taskinfo_res.DeleteAsync(taskInfo);
            lognote logfail = new lognote() { Type = "队列取消", User = "App", Note = $"起始-{taskInfo.StartName}目标{taskInfo.EndName}", DateTime = DateTime.Now };
            await LogNote_res.InsertAsync(logfail);
            return new ApiResponse("取消成功", true, null);
        }

        Task INotificationHandler<PostNotification>.Handle(PostNotification notification, CancellationToken cancellationToken)
        {
            Console.WriteLine("我收到了" + notification.Body);
            return Task.CompletedTask;
        }

     
    }
}
